package Q17_18_Shortest_Supersequence; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Queue; import CtCILibrary.HashMapList; public class QuestionD { public static Range getShortestClosure(ArrayList<Queue<Integer>> lists) { PriorityQueue<HeapNode> minHeap = new PriorityQueue<HeapNode>(); int max = Integer.MIN_VALUE; /* Insert min element from each list. */ for (int i = 0; i < lists.size(); i++) { int head = lists.get(i).remove(); minHeap.add(new HeapNode(head, i)); max = Math.max(max, head); } int min = minHeap.peek().locationWithinList; int bestRangeMin = min; int bestRangeMax = max; while (true) { /* Remove min node. */ HeapNode n = minHeap.poll(); Queue<Integer> list = lists.get(n.listId); /* Compare range to best range. */ min = n.locationWithinList; if (max - min < bestRangeMax - bestRangeMin) { bestRangeMax = max; bestRangeMin = min; } /* If there are no more elements, then there's no more subsequences and we can break. */ if (list.size() == 0) { break; } /* Add new head of list to heap. */ n.locationWithinList = list.remove(); minHeap.add(n); max = Math.max(max, n.locationWithinList); } return new Range(bestRangeMin, bestRangeMax); } /* Get list of queues (linked lists) storing the indices at which * each element in smallArray appears in bigArray. */ public static ArrayList<Queue<Integer>> getLocationsForElements(int[] big, int[] small) { /* Initialize hash map from item value to locations. */ HashMap<Integer, Queue<Integer>> itemLocations = new HashMap<Integer, Queue<Integer>>(); for (int s : small) { Queue<Integer> queue = new LinkedList<Integer>(); itemLocations.put(s, queue); } /* Walk through big array, adding the item locations to hash map */ for (int i = 0; i < big.length; i++) { Queue<Integer> queue = itemLocations.get(big[i]); if (queue != null) { queue.add(i); } } ArrayList<Queue<Integer>> allLocations = new ArrayList<Queue<Integer>>(); allLocations.addAll(itemLocations.values()); return allLocations; } public static Range shortestSupersequence(int[] big, int[] small) { ArrayList<Queue<Integer>> locations = getLocationsForElements(big, small); if (locations == null) return null; return getShortestClosure(locations); } public static void main(String[] args) { int[] array = {7, 5, 9, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 8, 9, 7}; int[] set = {1, 5, 9}; System.out.println(array.length); Range shortest = shortestSupersequence(array, set); if (shortest == null) { System.out.println("not found"); } else { System.out.println(shortest.getStart() + ", " + shortest.getEnd()); } } }